package com.hcbd.tdwt.base.bd;
import android.os.Handler;
import android.util.Log;

import com.hcbd.tdwt.MainApp;
import com.hcbd.tdwt.base.BdManager;
import com.hcbd.tdwt.base.BeidouBoxParams;
import com.hcbd.tdwt.base.Constant;
import com.hcbd.tdwt.base.SerialPortManage;
import com.hcbd.tdwt.base.hcbd.BdXyACKInfo;
import com.hcbd.tdwt.base.hcbd.BdXyZFIInfo;
import com.hcbd.tdwt.util.ConvertData;
import com.hcbd.tdwt.util.FileUtil;
import com.hcbd.tdwt.util.FileUtils;
import com.lrx.serialportlibrary.SerialPort;
import com.pangu.bdsdk2021.entity.terminalone.BDFKInfo;
import com.pangu.bdsdk2021.entity.terminalone.BDTXInfo;
import com.pangu.bdsdk2021.entity.terminalthree.BDSXXInfo;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;

// 华辰北斗手持机
// RD模块
public class XYSerialPortManage extends SerialPortManage {

    private String sys_path ="/dev/ttyS0";///dev/ttyS0  波特率115200
    private BdManager bdManager;
    public static String on_off_power_path="sys/devices/platform/pinctrl@1000b000/mt_gpio";  // 控制节点
//    private final String on_off_power_path="sys/devices/platform/pinctrl/mt_gpio";  // 控制节点
    //private final String on_off_power_path="sys/devices/platform/pinctrl/mt_gpio";
    private static  XYSerialPortManage xySerialPortManage;
    //北斗消息处理Handler
    private final Handler mHandler = new Handler(msg -> {
        switch (msg.what) {
            case 1:
                onPackageICAMsg(0,0);
                break;
            case 3:
                onPackageICR();
                break;
            case 4:
                String stringData = (String)msg.obj;
                MainApp.getInstance().showMsg(stringData);
                break;
        }
        return false;
    });
    public static XYSerialPortManage getInstance() {
        if (xySerialPortManage == null) {
            xySerialPortManage = new XYSerialPortManage();
            on_off_power_path = Constant.XY_HANDSET==Constant.P3? "sys/devices/platform/pinctrl@1000b000/mt_gpio":"/sys/devices/platform/pinctrl/mt_gpio";
            enable5V = Constant.XY_HANDSET==Constant.P3? "out 26 1":"out 31 1";
            disable5V = Constant.XY_HANDSET==Constant.P3? "out 26 0":"out 31 0";
            enableRD = Constant.XY_HANDSET==Constant.P3? "out 17 1":"out 32 1";
            disableRD = Constant.XY_HANDSET==Constant.P3? "out 17 0":"out 32 0";

            ANTENNA_I1 = Constant.XY_HANDSET==Constant.P3? "out 19 0":"out 34 0";
            ANTENNA_I2 = Constant.XY_HANDSET==Constant.P3? "out 20 0":"out 41 0";
            ANTENNA_E1 = Constant.XY_HANDSET==Constant.P3? "out 19 1":"out 34 1";
            ANTENNA_E2 = Constant.XY_HANDSET==Constant.P3? "out 20 1":"out 41 0";
        }
        return xySerialPortManage;
    }
    //通过文件路径判断是否是手持机
    public  boolean pdaCheck(){
        return new File(sys_path).exists() && new File(on_off_power_path).exists();
    }

    public XYSerialPortManage(){
        bdManager=BdManager.getInstance();
        logPath=FileUtil.getLogFile();
    }

    public static String enable5V = "out 26 1";public static String disable5V = "out 26 0";
    public static String enableRD = "out 17 1";public static String disableRD = "out 17 0";
    public static String ANTENNA_I1="out 19 0";public static String ANTENNA_I2="out 20 0";
    public static String ANTENNA_E1="out 19 1";public static String ANTENNA_E2="out 20 1";
    public void openXYSerialPort(){
        MainApp.getInstance().showLoading("正在打开北斗服务");
        try {
            //北斗模组
            setBDPowerState(enable5V);  // 上电
            openSerialPort(sys_path,baudRate);  // 打开RD模块
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            setBDPowerState(enableRD);  // 使能RDSS
            BdToolFactory.getBdSendBase().enableRD = true;
        }catch (Exception e){
            e.printStackTrace();
        }
        mHandler.sendEmptyMessageDelayed(3, 2000);
        mHandler.sendEmptyMessageDelayed(3, 3000);
        mHandler.sendEmptyMessageDelayed(3, 4000);
    }
    public void closeXYSerialPort(){
        BdToolFactory.getBdSendBase().enableRD = false;
        // 如果已经开启了RN则先不断电
//        if(!BdToolFactory.getBdSendBase().enableRN){
//            Log.e(TAG, "未开启RN模块" );
//            setBDPowerState("out 112 0");
//            setBDPowerState("out 25 0");
//            setBDPowerState(false);
//        }else {
//            Log.e(TAG, "未开启RN模块" );
//        }
//        setBDPowerState("out 32 0");
        //关闭串口
        Log.e(TAG, "关闭串口");
        closeSerialPort();
        setBDPowerState(disableRD);
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //延迟50ms
        setBDPowerState(disable5V);
        //关闭北斗设备
        bdManager.onDisconnect();
        FileUtils.writeFile(logPath,"close：--串口已关闭!");
    }


    public void setBDPowerState(String flag) {
        File file = new File(on_off_power_path);
        Log.e("power InfoMessage:", flag +" > "+on_off_power_path);
        FileUtils.writeFile(logPath,flag+"写入"+on_off_power_path);
        try {
            if (!file.exists()) {
                Log.e("InfoMessage", "BD /dev/bd1 not found!!");
                FileUtils.writeFile("InfoMessage",flag+"BD /dev/bd1 not found!!");
                return;
            }
            FileOutputStream fos = new FileOutputStream(file, false);
            BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(fos));
            bfw.write(flag);
            bfw.close();
            fos.close();
            Log.e(TAG, "power success!!" );
        } catch (FileNotFoundException e) {
            Log.e(TAG, "BD FileNotFoundException!!" + e);
            FileUtils.writeFile("InfoMessage","BD FileNotFoundException!"+e);
        } catch (IOException e) {
            Log.e(TAG, "BD IOException!!" + e);
            FileUtils.writeFile("InfoMessage","BD FileNotFoundException!"+e);
        }
    }

    @Override
    public  void  onReceived(String stringData){
        if("".equals(stringData)){
            return;
        }
        FileUtils.writeFile(FileUtil.getLogFile(),stringData);
        String[] values = stringData.split(",", -1);
//        Log.e(TAG, "正在解析: "+ Arrays.toString(values) );
        if (stringData.contains("ICP")) {//授权信息
            onReceiveBDICP(values);
        } else if (stringData.contains("PWI")) {//三代波束信息
            onReceiveBDPWI(values);
        }else if (stringData.contains("TCI")){//北三消息
            onReceiveBDTCI(values);
        }else if (stringData.contains("FKI")) {//反馈信息
            onReceiveFKI(values);
        }else if (stringData.contains("ACK")) {//ACK检测
            onReceiveBDACKThree(values);
        }else if (stringData.contains("BDICI")) {//北二信号
            onReceiveBDICI(values);
        }else if (stringData.contains("TXR")) {//北二消息
            onReceiveBDTXR(values);
        }
    }
    private void onReceiveBDICP(String[] values){
        try {
            BDSXXInfo bdsxxInfo=new BDSXXInfo();
            bdsxxInfo.user_id=String.valueOf(Integer.parseInt(values[1]));
            bdsxxInfo.regional_service_frequency=values[14];
            bdsxxInfo.cardType=values[15];
            if("2".equals(values[4])){
                BeidouBoxParams.card_model=2;
            }else{
                BeidouBoxParams.card_model=3;
            }
            bdManager.onBDSXXInfo(bdsxxInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void onReceiveBDTCI(String[] values){
        try {
            BDTXInfo bdtxInfo=new BDTXInfo();
            bdtxInfo.messageType=Integer.parseInt(values[5]);
            bdtxInfo.content=values[7];
            bdtxInfo.fromNumber=Integer.parseInt(values[1]);
            bdManager.onTXInfo(bdtxInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void onReceiveBDICI(String[] values){
        try{
            BDSXXInfo bdsxxInfo=new BDSXXInfo();
            bdsxxInfo.user_id=String.valueOf(Integer.parseInt(values[1]));
            bdsxxInfo.regional_service_frequency=String.valueOf(Integer.parseInt(values[5]));
            bdsxxInfo.cardType=String.valueOf(Integer.parseInt(values[6]));
            BeidouBoxParams.card_model=2;
            bdManager.onBDSXXInfo(bdsxxInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void onReceiveBDPWI(String[] values){
        if(BeidouBoxParams.card_model==2){
            bdManager.refreshSnrInfo(bdManager.onReceiveBDPWI(values));
        }else{
            bdManager.refreshSnrInfo(convertPwi(values));
        }
    }
    public int[] convertPwi(String[] values){
        int []s21 = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        try {
            int rdss2Count1 = Integer.parseInt(values[2]);
            int index = 2+rdss2Count1*3+1;
            int rdss3Count = Integer.parseInt(values[index]);
            index++;
            for (int i =0 ;i < rdss3Count; i++){
                int id = Integer.parseInt(values[index]);
                if (id > 21) continue;
                int number = Integer.parseInt(values[index+1]);
                s21[id-1] = number;
                if(values.length>index+3){
                    if ("0".equals(values[index+3])||"".equals(values[index+3])){
                        index += 4;
                    }else {
                        index += 3;
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return s21;
    }

    // [BDFKI, TXA, N, Y, 4, 0000]  北二
    // [BDFKI, 080432, TCQ, Y, 0, 0]  北三
    private void onReceiveFKI(String[] values){
        try {
            if(values[2].length()>2){
                Log.e(TAG, "北三fki");
                onReceiveBDFKIThree(values);
            }else{
                Log.e(TAG, "北二fki");
                onReceiveBDFKITwo(values);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

//        if(BeidouBoxParams.card_model==2){
//            onReceiveBDFKITwo(values);
//        }else{
//            onReceiveBDFKIThree(values);
//        }
    }
    private void onReceiveBDFKIThree(String[] values) {
        try {
            BDFKInfo bdfkInfo=new BDFKInfo();
            bdfkInfo.state=values[3];
            bdfkInfo.res=values[4];
            bdManager.onFKInfo(bdfkInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void onReceiveBDFKITwo(String[] values) {
        try {
            BDFKInfo bdfkInfo=new BDFKInfo();
            bdfkInfo.state=values[2];
            bdfkInfo.res=values[4];
            MainApp.getInstance().showMsg("收到北二反馈:"+values);
            bdManager.onFKInfo(bdfkInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void onReceiveBDTXR(String[] values){
        try {
            BDTXInfo bdtxInfo=new BDTXInfo();
            bdtxInfo.messageType=Integer.parseInt(values[3]);
            bdtxInfo.content=values[5];
            bdtxInfo.fromNumber=Integer.parseInt(values[2]);
            bdManager.onTXInfo(bdtxInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    // $BDACK,947,113510.432,103,61,3,2,1,4194441,0,0*55
    // BDACK,947,118067.405,103,61,3,2,1,4194441,0,1
    private void onReceiveBDACKThree(String[] values) {
        try {
            BdXyACKInfo ackInfo = new BdXyACKInfo();
            if(values[6].contains("2")){
                ackInfo.type="2";
            }else{
                ackInfo.type="0";
            }
            bdManager.onBdACKInfo(ackInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 自毁响应信息
     * @param values
     */
    private void onReceiveBDZFIThree(String[] values) {
        BdXyZFIInfo bdzfinfo=new BdXyZFIInfo();
        bdzfinfo.type=values[1];
        bdzfinfo.result=values[2];
        bdManager.onBdZFIInfo(bdzfinfo);
    }

    public boolean onPackageICAMsg(int type, int frame) {
        byte Xor = 0;
        String icaContent = "$CCICA," + type + "," + frame + "," + "*";

        try {
            byte[] ICABytes = icaContent.getBytes("GB2312");
            byte[] ICAMsg = new byte[ICABytes.length + 4];

            for(int i = 1; i < ICABytes.length - 1; ++i) {
                Xor ^= ICABytes[i];
            }

            System.arraycopy(ICABytes, 0, ICAMsg, 0, ICABytes.length);
            ICAMsg[ICABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
            ICAMsg[ICABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
            ICAMsg[ICABytes.length + 2] = 13;
            ICAMsg[ICABytes.length + 3] = 10;
            this.sendBytes(ICAMsg, ICAMsg.length);
            return true;
        } catch (Exception var8) {
            Log.d("BDProtocol", "onPackageICAMsg change byte error!!! ");
            return false;
        }
    }
    public boolean onPackageICR() {
        byte Xor = 0;
        String icaContent = "$CCICR,0,00*";
        try {
            byte[] ICABytes = icaContent.getBytes("GB2312");
            byte[] ICAMsg = new byte[ICABytes.length + 4];

            for(int i = 1; i < ICABytes.length - 1; ++i) {
                Xor ^= ICABytes[i];
            }
            System.arraycopy(ICABytes, 0, ICAMsg, 0, ICABytes.length);
            ICAMsg[ICABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
            ICAMsg[ICABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
            ICAMsg[ICABytes.length + 2] = 13;
            ICAMsg[ICABytes.length + 3] = 10;
            this.sendBytes(ICAMsg, ICAMsg.length);
            return true;
        } catch (Exception var8) {
            Log.d("BDProtocol", "onPackageICAMsg change byte error!!! ");
            return false;
        }
    }

    /**
     * 发送自毁北斗模块指令
     * @param Category
     * @return
     */
    public boolean onPackageCCZHS(int Category) {
        byte Xor = 0;
        String icaContent = "$CCZHS,"+Category+"*";
        try {
            byte[] ICABytes = icaContent.getBytes("GB2312");
            byte[] ICAMsg = new byte[ICABytes.length + 4];

            for(int i = 1; i < ICABytes.length - 1; ++i) {
                Xor ^= ICABytes[i];
            }
            System.arraycopy(ICABytes, 0, ICAMsg, 0, ICABytes.length);
            ICAMsg[ICABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
            ICAMsg[ICABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
            ICAMsg[ICABytes.length + 2] = 13;
            ICAMsg[ICABytes.length + 3] = 10;
            this.sendBytes(ICAMsg, ICAMsg.length);
            return true;
        } catch (Exception var8) {
            Log.d("BDProtocol", "onPackageICAMsg change byte error!!! ");
            return false;
        }
    }

    // $CCEPQ,4215868,2,1,2,2,0,0,0,100,4,0000*6A  // 旧
    public boolean onSendCCEPQ(String TheReceivingPartyID,int EmergencySigns, int ElevationValue, int SearchAndRescueType) {
        byte Xor = 0;
        String icaContent = "$CCEPQ,"+TheReceivingPartyID+",1,2,1,"+ EmergencySigns +","+ ElevationValue+","+ SearchAndRescueType +",0,100,,*";
        try {
            byte[] ICABytes = icaContent.getBytes("GB2312");
            byte[] ICAMsg = new byte[ICABytes.length + 4];

            for(int i = 1; i < ICABytes.length - 1; ++i) {
                Xor ^= ICABytes[i];
            }
            System.arraycopy(ICABytes, 0, ICAMsg, 0, ICABytes.length);
            ICAMsg[ICABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
            ICAMsg[ICABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
            ICAMsg[ICABytes.length + 2] = 13;
            ICAMsg[ICABytes.length + 3] = 10;
            this.sendBytes(ICAMsg, ICAMsg.length);
            return true;
        } catch (Exception var8) {
            Log.d("BDProtocol", "onPackageICAMsg change byte error!!! ");
            return false;
        }
    }
    public boolean onPackageThroughCCTCQ(int type,int frePoint,String phoneNum, String message) {
        byte Xor = 0;
        byte[] TXABytes = null;
        if (type != 2 && type != 3 && type != 1 && type != 9) {
            return false;
        } else {
            String txaContent = "$CCTCQ,"+phoneNum + ","+frePoint+","+1+"," + type + ",";

            try {
                byte[] TXAMsg = null;
                txaContent = txaContent + message + ",0*";
                TXABytes = txaContent.getBytes("GB18030");
                TXAMsg = new byte[TXABytes.length + 4];
                System.arraycopy(TXABytes, 0, TXAMsg, 0, TXABytes.length);

                for(int i = 1; i < TXAMsg.length - 5; ++i) {
                    Xor ^= TXAMsg[i];
                }

                TXAMsg[TXABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
                TXAMsg[TXABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
                TXAMsg[TXABytes.length + 2] = 13;
                TXAMsg[TXABytes.length + 3] = 10;
                this.sendBytes(TXAMsg, TXAMsg.length);
                return true;
            } catch (Exception var9) {
                Log.d("BDProtocol", "onPackageTXAMsg change byte error!!! ");
                return false;
            }
        }
    }
    public void sendBytes(byte[] paramArrayOfByte, int size){
        //发送数据到北斗模块
        try {
            byte[] sendByte = new byte[size];
            if (paramArrayOfByte == null || paramArrayOfByte.length < size) {
                return;
            }
            System.arraycopy(paramArrayOfByte, 0, sendByte, 0, size);
            String str=new String(sendByte,"GB2312");
            Log.e("sendBytes:",str);
            FileUtils.writeFile(logPath,"sned：--"+str);
            mOutputStream.write(sendByte);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendCustomCommand(String command){
        byte Xor = 0;
        String icaContent = "$"+command+"*";
        try {
            byte[] ICABytes = icaContent.getBytes("GB2312");
            byte[] ICAMsg = new byte[ICABytes.length + 4];

            for(int i = 1; i < ICABytes.length - 1; ++i) {
                Xor ^= ICABytes[i];
            }
            System.arraycopy(ICABytes, 0, ICAMsg, 0, ICABytes.length);
            ICAMsg[ICABytes.length] = (byte)this.byteToChar((byte)(Xor >> 4));
            ICAMsg[ICABytes.length + 1] = (byte)this.byteToChar((byte)(Xor & 15));
            ICAMsg[ICABytes.length + 2] = 13;
            ICAMsg[ICABytes.length + 3] = 10;
            this.sendBytes(ICAMsg, ICAMsg.length);
            Log.e(TAG, "下发自定义指令："+ConvertData.bytes2string(ICAMsg));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void tailoringInstruction(String stringData){
        //查找校验和
        int xorIndex = stringData.indexOf("*");
        //<语句类型标识>, <数据字段1>,<数据字段2>, ..., <数据字段n>
        if (xorIndex != -1) {
            stringData = stringData.substring(0, xorIndex);
        }
        String []data=stringData.split("\\$");
//        Arrays.stream(data)
//                .filter(str->{
//                    return str.length()>2;
//                })
//                .peek(str->{
//                    Log.e(TAG, "需要解析的rd指令原始数据: "+str );
//                    onReceived(str);
//                });
        for(String str:data){
            if(str.length()>2){
                Log.e(TAG, "需要解析的rd指令原始数据: "+str );
                onReceived(str);
            }
        }
    }

}
